package com.example.com.transcribeeditpublish.activity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.widget.PopupWindow;
import android.widget.Toast;

import com.example.com.transcribeeditpublish.PlayState;
import com.example.com.transcribeeditpublish.R;
import com.example.com.transcribeeditpublish.BR;
import com.example.com.transcribeeditpublish.TCVideoEditerWrapper;
import com.example.com.transcribeeditpublish.databinding.ActivityVideoEditBinding;
import com.example.com.transcribeeditpublish.myInterface.IOnBeautyParamsChangeListener;
import com.example.com.transcribeeditpublish.popuWindow.BeautyPpwindow;
import com.example.com.transcribeeditpublish.popuWindow.CutMusicPpWindow;
import com.example.com.transcribeeditpublish.popuWindow.PasterPpWindow;
import com.example.com.transcribeeditpublish.popuWindow.SelectBbmPpWindow;
import com.example.com.transcribeeditpublish.popuWindow.SetVoicePpWindow;
import com.example.com.transcribeeditpublish.utils.FileUtils;
import com.example.com.transcribeeditpublish.utils.TCBGMInfo;
import com.example.com.transcribeeditpublish.utils.TCConstants;
import com.example.com.transcribeeditpublish.utils.TCEditerUtil;
import com.example.com.transcribeeditpublish.utils.TCPasterInfo;
import com.example.com.transcribeeditpublish.utils.TCUtils;
import com.example.com.transcribeeditpublish.utils.beauty.BeautyParams;
import com.example.com.transcribeeditpublish.utils.paster.TCPasterOperationViewFactory;
import com.example.com.transcribeeditpublish.views.RangeSlider;
import com.example.com.transcribeeditpublish.views.RangeSliderViewContainer;
import com.example.com.transcribeeditpublish.views.VideoWorkProgressFragment;
import com.example.com.transcribeeditpublish.views.paster.PasterOperationView;
import com.example.com.transcribeeditpublish.views.paster.TCLayerOperationView;
import com.example.com.transcribeeditpublish.views.paster.TCLayerViewGroup;
import com.tencent.liteav.basic.log.TXCLog;
import com.tencent.ugc.TXVideoEditConstants;
import com.tencent.ugc.TXVideoEditer;
import com.tencent.ugc.TXVideoInfoReader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import me.goldze.mvvmhabit.base.BaseActivity;
import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.utils.BaseUrlExternalStrageDir;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.ToastUtils;

public class VideoEditActivity extends BaseActivity<ActivityVideoEditBinding, BaseViewModel> implements
        TCVideoEditerWrapper.TXVideoPreviewListenerWrapper, View.OnClickListener, TCLayerOperationView.IOperationViewClickListener,
        TCLayerViewGroup.OnItemClickListener, PopupWindow.OnDismissListener, TXVideoEditer.TXVideoGenerateListener {


    private TCVideoEditerWrapper mEditerWrapper;
    private TXVideoEditer mTXVideoEditer;
    private long mVideoDuration;
    private String mvideoPath;
    private int mCurrentState = PlayState.STATE_NONE;
    private long mPreviewAtTime;
    private SetVoicePpWindow mSetVoicePpWindow; //设置声音大小
    private SelectBbmPpWindow selectBbmPpWindow; //选择bgm
    private TCBGMInfo currentBgmInfo; //当前bgm信息
    private CutMusicPpWindow cutMusicPpWindow; //裁剪音乐
    private PasterPpWindow pasterPpWindow; //贴纸
    private String TAG = "VideoEditActivity";
    public static String PASTER_FOLDER_NAME = "paster";
    public static String ANIMATED_PASTER_FOLDER_NAME = "AnimatedPaster";
    public static String mPasterSDcardFolder = BaseUrlExternalStrageDir.getBaseUrl() + File.separator + PASTER_FOLDER_NAME + File.separator;
    public static String mAnimatedPasterSDcardFolder = BaseUrlExternalStrageDir.getBaseUrl() + File.separator + ANIMATED_PASTER_FOLDER_NAME + File.separator;
    private BeautyPpwindow beautyPpwindow; //滤镜
    private String mVideoOutputPath;
    private VideoWorkProgressFragment mWorkLoadingProgress;
    private String mCoverPath;

    @Override
    public void onPreviewProgressWrapper(int timeMs) {
        // KLog.e("ProgressWrapper", "time");
    }

    @Override
    public void onPreviewFinishedWrapper() {
        if (mCurrentState == PlayState.STATE_PREVIEW_AT_TIME) {
            return;
        }
        stopPlay();
        // 如果当前不是动态滤镜界面或者时间特效界面，那么会自动开始重复播放;
        startPlay(getCutterStartTime(), getCutterEndTime());

    }

    @Override
    public int initContentView() {
        return R.layout.activity_video_edit;
    }

    @Override
    public int initVariableId() {
        return BR.entity;
    }

    @Override
    public BaseViewModel initViewModel() {
        return new BaseViewModel(this);
    }

    @Override
    public void initData() {
        super.initData();

        initView();
        initPlayerLayout();
        initListener();
    }

    private void initView() {
        mvideoPath = getIntent().getStringExtra(TCConstants.VIDEO_EDITER_PATH);
        mCoverPath = getIntent().getStringExtra(TCConstants.VIDEO_RECORD_COVERPATH);
        mEditerWrapper = TCVideoEditerWrapper.getInstance();
        mEditerWrapper.addTXVideoPreviewListenerWrapper(this);
        if (TextUtils.isEmpty(mvideoPath)) {
            Toast.makeText(this, "发生未知错误,路径不能为空", Toast.LENGTH_SHORT).show();
            finish();
        }
        mTXVideoEditer = mEditerWrapper.getEditer();
        if (mTXVideoEditer == null || mEditerWrapper.getTXVideoInfo() == null) {
            Toast.makeText(this, "状态异常，结束编辑", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        mVideoDuration = mEditerWrapper.getTXVideoInfo().duration;
        mEditerWrapper.setCutterStartTime(0, mVideoDuration);


        mSetVoicePpWindow = new SetVoicePpWindow(this);
        selectBbmPpWindow = new SelectBbmPpWindow(this, new SelectBbmPpWindow.BGMCallBack() {
            @Override
            public void select(TCBGMInfo bgmInfo) {
                currentBgmInfo = bgmInfo;
                if (bgmInfo != null) {
                    stopPlay();
                    startPlay(getCutterStartTime(), getCutterEndTime());
                }
            }
        });
        cutMusicPpWindow = new CutMusicPpWindow(this, new RangeSlider.OnRangeChangeListener() {
            @Override
            public void onKeyDown(int type) {
            }

            @Override
            public void onKeyUp(int type, int leftPinIndex, int rightPinIndex) {
                long startTime = currentBgmInfo.getDuration() * leftPinIndex / 100; //ms
                long rightTime = currentBgmInfo.getDuration() * rightPinIndex / 100;
                mTXVideoEditer.setBGMStartTime(startTime, rightTime);
            }
        });
        pasterPpWindow = new PasterPpWindow(this, new PasterPpWindow.OnItemClickListener() {
            @Override
            public void onItemClick(TCPasterInfo tcPasterInfo, String pasterPath, Bitmap bitmap) {
                selectPaster(tcPasterInfo, pasterPath, bitmap);
            }
        });
        beautyPpwindow = new BeautyPpwindow(this, new IOnBeautyParamsChangeListener() {
            @Override
            public void onBeautyParamsChange(BeautyParams params, int key) {
                settingBeauty(params, key);
            }
        });

    }


    private void initListener() {
        getBinding().pause.setOnClickListener(this);
        getBinding().setVoice.setOnClickListener(this);
        getBinding().selectBgm.setOnClickListener(this);
        getBinding().cutMusic.setOnClickListener(this);
        getBinding().setPaster.setOnClickListener(this);
        getBinding().pasterContainer.setOnItemClickListener(this);
        getBinding().pasterContainer.setOnClickListener(this);
        getBinding().showBeauty.setOnClickListener(this);
        getBinding().next.setOnClickListener(this);
        getBinding().back.setOnClickListener(this);
        mSetVoicePpWindow.setOnDismissListener(this);
        selectBbmPpWindow.setOnDismissListener(this);
        cutMusicPpWindow.setOnDismissListener(this);
        pasterPpWindow.setOnDismissListener(this);
        beautyPpwindow.setOnDismissListener(this);

    }

    private void initPlayerLayout() {
        TXVideoEditConstants.TXPreviewParam param = new TXVideoEditConstants.TXPreviewParam();
        param.videoView = getBinding().videoContianer;
        param.renderMode = TXVideoEditConstants.PREVIEW_RENDER_MODE_FILL_SCREEN;
        mTXVideoEditer.initWithPreview(param);
    }


    private long getCutterStartTime() {
        return mEditerWrapper.getCutterStartTime();
    }

    private long getCutterEndTime() {
        return mEditerWrapper.getCutterEndTime();
    }


    private void selectPaster(TCPasterInfo tcPasterInfo, String pasterPath, Bitmap bitmap) {
        PasterOperationView pasterOperationView = TCPasterOperationViewFactory.newOperationView(this);
        pasterOperationView.setPasterPath(pasterPath);
        pasterOperationView.setChildType(tcPasterInfo.getPasterType());
        pasterOperationView.setImageBitamp(bitmap);
        pasterOperationView.setCenterX(getBinding().pasterContainer.getWidth() / 2);
        pasterOperationView.setCenterY(getBinding().pasterContainer.getHeight() / 2);
        pasterOperationView.setStartTime(getCutterStartTime(), getCutterEndTime());
        pasterOperationView.setIOperationViewClickListener(this);

        pasterOperationView.setPasterName(tcPasterInfo.getName());

        getBinding().pasterContainer.addOperationView(pasterOperationView);
        getBinding().pasterContainer.post(new Runnable() {
            @Override
            public void run() {
                addPasterListVideo();
            }
        });
    }

    private void settingBeauty(BeautyParams params, int key) {
        if (mTXVideoEditer != null) {
            mTXVideoEditer.setFilter(params.mFilterBmp);
        }
        doTextAnimator(params);
    }


    private void doTextAnimator(BeautyParams params) {
        // 设置当前滤镜的名字
        getBinding().tvFilter.setText(beautyPpwindow.getBeautyFilterArr()[params.filterIndex]);
        AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
        alphaAnimation.setDuration(400);
        alphaAnimation.setInterpolator(new LinearInterpolator());
        alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                getBinding().tvFilter.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                getBinding().tvFilter.setVisibility(View.GONE);
                // mIsDoingAnimator = false;
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        getBinding().tvFilter.startAnimation(alphaAnimation);
    }

    public void startPlay(long startTime, long endTime) {
        if (mCurrentState == PlayState.STATE_NONE || mCurrentState == PlayState.STATE_STOP || mCurrentState == PlayState.STATE_PREVIEW_AT_TIME) {
            mTXVideoEditer.startPlayFromTime(startTime, endTime);
            mCurrentState = PlayState.STATE_PLAY;
            getBinding().pause.setVisibility(View.GONE);
        }
    }

    public void resumePlay() {
        if (mCurrentState == PlayState.STATE_PAUSE) {
            mTXVideoEditer.resumePlay();
            mCurrentState = PlayState.STATE_RESUME;
        }
    }

    public void pausePlay() {
        if (mCurrentState == PlayState.STATE_RESUME || mCurrentState == PlayState.STATE_PLAY) {
            mTXVideoEditer.pausePlay();
            mCurrentState = PlayState.STATE_PAUSE;
            // getBinding().pause.setVisibility(View.VISIBLE);
        }
    }

    public void stopPlay() {
        if (mCurrentState == PlayState.STATE_RESUME || mCurrentState == PlayState.STATE_PLAY ||
                mCurrentState == PlayState.STATE_PREVIEW_AT_TIME || mCurrentState == PlayState.STATE_PAUSE) {
            mTXVideoEditer.stopPlay();
            mCurrentState = PlayState.STATE_STOP;
        }
    }

    public void playVideo() {
        if (mCurrentState == PlayState.STATE_NONE || mCurrentState == PlayState.STATE_STOP) {
            KLog.e("Start", "getCutterStartTime=" + getCutterStartTime() + " , getCutterEndTime=" + getCutterEndTime());
            startPlay(getCutterStartTime(), getCutterEndTime());

        } else if ((mCurrentState == PlayState.STATE_RESUME || mCurrentState == PlayState.STATE_PLAY)) {
            pausePlay();
        } else if (mCurrentState == PlayState.STATE_PAUSE) {
            resumePlay();
        } else if (mCurrentState == PlayState.STATE_PREVIEW_AT_TIME) {
            if ((mPreviewAtTime >= getCutterEndTime() || mPreviewAtTime <= getCutterStartTime())) {
                startPlay(getCutterStartTime(), getCutterEndTime());
            } else if (!TCVideoEditerWrapper.getInstance().isReverse()) {
                startPlay(mPreviewAtTime, getCutterEndTime());
            } else {
                startPlay(getCutterStartTime(), mPreviewAtTime);
            }
        }
    }


    @Override
    protected void onResume() {
        super.onResume();
        mEditerWrapper.addTXVideoPreviewListenerWrapper(this);
        playVideo();
    }

    @Override
    protected void onPause() {
        super.onPause();
        pausePlay();
        // 若当前处于生成状态，离开当前activity，直接停止生成
        if (mCurrentState == PlayState.STATE_GENERATE) {
            stopGenerate();
        }
        mEditerWrapper.removeTXVideoPreviewListenerWrapper(this);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mTXVideoEditer != null) {
            stopPlay();
            mTXVideoEditer.setVideoGenerateListener(null);
            //编辑完成后，销毁资源，避免影响处理下一个视频
            mTXVideoEditer.release();
            mTXVideoEditer = null;
        }
        // 清除对TXVideoEditer的引用以及相关配置
        mEditerWrapper.removeTXVideoPreviewListenerWrapper(this);
        mEditerWrapper.cleaThumbnails();
        mEditerWrapper.clear();
    }


    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.select_bgm) {
            selectBbmPpWindow.show(this);
            getBinding().buttomTool.setVisibility(View.GONE);
        } else if (id == R.id.set_voice) {
            mSetVoicePpWindow.show(this);
            getBinding().buttomTool.setVisibility(View.GONE);
        } else if (id == R.id.cut_music) {
            if (haseBGM()) {
                cutMusicPpWindow.show(this);
                getBinding().buttomTool.setVisibility(View.GONE);
            } else {
                ToastUtils.showShort("请先选择音乐");
            }
        } else if (id == R.id.set_paster) {
            pasterPpWindow.show(this);
            getBinding().buttomTool.setVisibility(View.GONE);
        } else if (id == R.id.paster_container) {
            if (getBinding().pasterContainer.getmLastSelectedPos() != -1) {
                getBinding().pasterContainer.selectOperationView(-1);
                addPasterListVideo();
            }
        } else if (id == R.id.show_beauty) {
            beautyPpwindow.show(this);
            getBinding().buttomTool.setVisibility(View.GONE);
        } else if (id == R.id.next) {
            startGenerateVideo();
        } else if (id == R.id.back) {
            finish();
        }
    }

    @Override
    public void onLayerOperationViewItemClick(TCLayerOperationView view, int lastSelectedPos, int currentSelectedPos) {
        addPasterListVideo();
        //stopPlay();
    }

    public boolean haseBGM() {
        return currentBgmInfo != null;
    }

    public TXVideoEditer getTXCameraRecord() {
        return mTXVideoEditer;
    }


    /**
     * ===========================将贴纸添加到SDK中去=================================
     */

    private void addPasterListVideo() {
        List<TXVideoEditConstants.TXAnimatedPaster> animatedPasterList = new ArrayList<>();
        List<TXVideoEditConstants.TXPaster> pasterList = new ArrayList<>();
        for (int i = 0; i < getBinding().pasterContainer.getChildCount(); i++) {
            PasterOperationView view = (PasterOperationView) getBinding().pasterContainer.getOperationView(i);
            TXVideoEditConstants.TXRect rect = new TXVideoEditConstants.TXRect();
            rect.x = view.getImageX();
            rect.y = view.getImageY();
            rect.width = view.getImageWidth();
            //   TXCLog.i(TAG, "addPasterListVideo, adjustPasterRect, paster x y = " + rect.x + "," + rect.y);

            if (view.isEditable()) {
                continue;
            }
            TXCLog.i(TAG, "aisEditable =" + view.isEditable());
            int childType = view.getChildType();
            if (childType == PasterOperationView.TYPE_CHILD_VIEW_ANIMATED_PASTER) {
                TXVideoEditConstants.TXAnimatedPaster txAnimatedPaster = new TXVideoEditConstants.TXAnimatedPaster();
                txAnimatedPaster.animatedPasterPathFolder = mAnimatedPasterSDcardFolder + view.getPasterName() + File.separator;
                txAnimatedPaster.startTime = view.getStartTime();
                txAnimatedPaster.endTime = view.getEndTime();
                txAnimatedPaster.frame = rect;
                txAnimatedPaster.rotation = view.getImageRotate();
                animatedPasterList.add(txAnimatedPaster);

            } else if (childType == PasterOperationView.TYPE_CHILD_VIEW_PASTER) {
                TXVideoEditConstants.TXPaster txPaster = new TXVideoEditConstants.TXPaster();
                txPaster.pasterImage = view.getRotateBitmap();
                txPaster.startTime = view.getStartTime();
                txPaster.endTime = view.getEndTime();
                txPaster.frame = rect;
                pasterList.add(txPaster);
            }

        }
        TXCLog.i(TAG, "animatedPasterList =" + animatedPasterList.size());
        mTXVideoEditer.setAnimatedPasterList(animatedPasterList);
        mTXVideoEditer.setPasterList(pasterList);

    }

    //-----------------------------------贴纸编辑-----------------------
    @Override
    public void onDeleteClick() {
        PasterOperationView view = (PasterOperationView) getBinding().pasterContainer.getSelectedLayerOperationView();
        if (view != null) {
            getBinding().pasterContainer.removeOperationView(view);
        }
        addPasterListVideo();
    }

    @Override
    public void onEditClick() {
        // addPasterListVideo();
        ToastUtils.showShort("没写完(~_~)");
    }

    @Override
    public void onRotateClick() {
        // addPasterListVideo();
    }

    @Override
    public void onDismiss() {
        getBinding().buttomTool.setVisibility(View.VISIBLE);
    }


    /**
     * =========================================视频生成相关==========================================
     */
    private void startGenerateVideo() {
        stopPlay(); // 停止播放
        mTXVideoEditer.cancel(); // 注意：生成时，停止输出缩略图

        // 处于生成状态
        mCurrentState = PlayState.STATE_GENERATE;
        // 防止
        getBinding().next.setEnabled(false);
        getBinding().next.setClickable(false);
        // 生成视频输出路径
        mVideoOutputPath = TCEditerUtil.generateVideoPath();

        if (mWorkLoadingProgress == null) {
            initWorkLoadingProgress();
        }
        mWorkLoadingProgress.setProgress(0);
        mWorkLoadingProgress.setCancelable(false);
        mWorkLoadingProgress.show(getSupportFragmentManager(), "progress_dialog");

        // 添加片尾水印
        //   addTailWaterMark();

        mTXVideoEditer.setCutFromTime(getCutterStartTime(), getCutterEndTime());
        mTXVideoEditer.setVideoGenerateListener(this);

//        if (mCustomBitrate != 0) { // 是否自定义码率
//            mTXVideoEditer.setVideoBitrate(mCustomBitrate);
//        }
        mTXVideoEditer.generateVideo(TXVideoEditConstants.VIDEO_COMPRESSED_720P, mVideoOutputPath);

    }

    private void stopGenerate() {
        if (mWorkLoadingProgress != null) {
            mWorkLoadingProgress.setProgress(0);
            mWorkLoadingProgress.dismiss();
        }
        if (mCurrentState == PlayState.STATE_GENERATE) {
            getBinding().next.setEnabled(true);
            getBinding().next.setClickable(true);
            Toast.makeText(this, "取消视频生成", Toast.LENGTH_SHORT).show();
            mCurrentState = PlayState.STATE_NONE;
            if (mTXVideoEditer != null) {
                mTXVideoEditer.cancel();
            }
        }
    }

    @Override
    public void onGenerateProgress(float progress) {
        mWorkLoadingProgress.setProgress((int) (progress * 100));
    }

    @Override
    public void onGenerateComplete(TXVideoEditConstants.TXGenerateResult result) {
        if (result.retCode == TXVideoEditConstants.GENERATE_RESULT_OK) {
            // 生成成功
            createThumbFile(result);
        } else {
            Toast.makeText(this, result.descMsg, Toast.LENGTH_SHORT).show();
            mWorkLoadingProgress.dismiss();
        }
        getBinding().next.setEnabled(true);
        getBinding().next.setClickable(true);
        mCurrentState = PlayState.STATE_NONE;
    }

    /**
     * 创建缩略图，并跳转至视频预览的Activity
     */
    private void createThumbFile(final TXVideoEditConstants.TXGenerateResult result) {

        AsyncTask<Void, String, String> task = new AsyncTask<Void, String, String>() {
            @Override
            protected String doInBackground(Void... voids) {
                File outputVideo = new File(mVideoOutputPath);
                if (!outputVideo.exists())
                    return null;
                Bitmap bitmap = TXVideoInfoReader.getInstance().getSampleImage(0, mVideoOutputPath);
                if (bitmap == null)
                    return null;
                String folder = BaseUrlExternalStrageDir.getBaseUrl() + File.separator + "video";

                File appDir = new File(folder);
                if (!appDir.exists()) {
                    appDir.mkdirs();
                }

                String fileName = "thumbnail" + ".jpg";
                File file = new File(appDir, fileName);
                try {
                    FileOutputStream fos = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                    fos.flush();
                    fos.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return file.getAbsolutePath();
            }

            @Override
            protected void onPostExecute(String s) {
                FileUtils.deleteFile(mvideoPath);
                FileUtils.deleteFile(mCoverPath);
                startPreviewActivity(result, s);
            }
        };
        task.execute();
    }

    private void startPreviewActivity(TXVideoEditConstants.TXGenerateResult result, String thumbPath) {
        mWorkLoadingProgress.dismiss();
        Intent intent = new Intent(this, PreviewActvity.class);
        // intent.putExtra(TCConstants.VIDEO_RECORD_TYPE, TCConstants.VIDEO_RECORD_TYPE_EDIT);
        intent.putExtra(TCConstants.VIDEO_RECORD_VIDEPATH, mVideoOutputPath);
        if (thumbPath != null)
            intent.putExtra(TCConstants.VIDEO_RECORD_COVERPATH, thumbPath);
        intent.putExtra(TCConstants.VIDEO_RECORD_DURATION, getCutterEndTime() - getCutterStartTime());
        startActivity(intent);
        // finish();
    }

    /**
     * ==========================================进度条==========================================
     */
    private void initWorkLoadingProgress() {
        if (mWorkLoadingProgress == null) {
            mWorkLoadingProgress = new VideoWorkProgressFragment();
        }
        mWorkLoadingProgress.setProgress(0);
    }
}

